// 函数 

// 一、函数的参数

// 定义函数
function foo(x,y){
    console.log(x,y);
}

// 调用函数
foo("hello","aaaaa");

// 1. 参数默认值

// ES5 方式：不严谨
function foo2(x,y){
    y=y||"world"
    console.log(x,y);
}

foo2("hello");
foo2("hello",0); //hello world

// ES6 方式：通常把带有参数默认值的参数放到后面
function foo3(x,y="world"){
    console.log(x,y);
}

foo3("hello");//hello world
foo3("hello",0);//hello 0
foo3("hello",undefined);//hello world

// 2. 与解构赋值结合

function ajax(url,{
    method="GET",
    headers={},
    body=""
}={}){
    console.log(method);
}

ajax("https://www.baidu.com");//GET

ajax("https://www.baidu.com",{
    method:"POST"
});//POST

// 3.length属性：没有设置参数默认值的参数个数

function bar(z,x=1,y=2){
    console.log(x,y,z);
}

bar()

console.log(bar.length); //1

// 4.参数作用域

{
    let x=1;
    function demo(x,y=x){
        console.log(x,y);
    }
    demo(2)
}

{
    //作用域链：当在JS中使用一个变量的时候，首先JS会尝试在当前作用域下去寻找该变量，如果没有找到，再到它的上一层作用域中寻找
    // 以此类推直到找到该变量为止。
    let x=1;
    function demo(y=x){
        let x=2;
        console.log(y);
    }
    demo()//1
}

// {
//     //作用域链：当在JS中使用一个变量的时候，首先JS会尝试在当前作用域下去寻找该变量，如果没有找到，再到它的上一层作用域中寻找
//     // 以此类推直到找到该变量为止。
//     function demo(y=x){
//         let x=2;
//         console.log(y);
//     }
//     demo()//Uncaught ReferenceError: x is not defined
// }

// 二、扩展运算符与rest(剩余)参数

// ...

// 1.扩展运算符：将数组元素按照,进行处理

{
    // 解构赋值
    function text([a,b,c]){
        console.log(a,b,c);
    }
    
    let arr=[1,2,3];
    text(arr);
}

{
    // ...
    function text(a,b,c){
        console.log(a,b,c);
    }
    
    let arr=[1,2,3];

    text(...arr);
}

// 例子：合并数组

{
    // ES5方式
    let arr1=[1,2,3];
    let arr2=[4,5,6];
    // [1,2,3,4,5,6]

    Array.prototype.push.apply(arr1,arr2);
    console.log(arr1);
}

{
    // ES6方式
    let arr1=[1,2,3];
    let arr2=[4,5,6];

    arr1.push(...arr2)//[4,5,6]=>4,5,6
    console.log(arr1);

    let word="xxxxx";
    console.log(...word);
}

// 2.rest参数（剩余参数）

// 例子：计算函数所有参数的和
{
    // ES5 方式：使用arguments 结合forEach会报错
    function foo(){
        //arguments参数数组，这是一个伪数组
        console.log(arguments);
        let result=0;
        arguments.forEach(function(value){
            result+=value
        });
        return result;
    }
    // foo()//Uncaught TypeError: arguments.forEach is not a function
}

{
    // ES5 方式：使用arguments 结合Array对象提供的原型方法 forEach
    function foo(){
        let result=0;
        Array.prototype.forEach.call(arguments,function(value){
            result+=value
        });
        return result;
    }
    console.log(foo());
    console.log(foo(1));
    console.log(foo(1,2));
    console.log(foo(1,2,3,5,89));
}


{
    // ES6方式：使用rest参数（...）
    function foo(...args){
        // console.log(args);
        let result =0;
        args.forEach(function(value){
            result+=value
        })
        return result;
    }

    console.log(foo());
    console.log(foo(1));
    console.log(foo(1,2));
    console.log(foo(1,2,3,5,89));
}

let [x,...y]=[1,2,3,4];
console.log(x,y);